from base import BaseItem
import pygame, time, random
from Bullet import Bullet
from Map import Map, SCREEN_HEIGHT, SCREEN_WIDTH, INIT_X, INIT_Y
from Wall import Wall
from Item import Item


class Character(BaseItem):
    """
    Character class, an abstract class
    """

    def __init__(self, left, top, speed):
        """
        Args:
            left: initial x0
            top:  initial y0
            speed: initial speed
        """
        super(Character, self).__init__()
        self.characterType = None
        # set the position of the tank
        self.rect.left = left
        self.rect.top = top
        # direction
        self.direction = None
        # multiImages
        self.images = {'U': None, 'D': None, 'L': None, 'R': None}
        # move speed
        self.speed = speed
        # stop/move flag
        self.stop = True
        # live flag
        self.live = True
        # position cache
        self.oldLeft = self.rect.left
        self.oldTop = self.rect.top

    def move(self):
        """character will move by four direction"""
        self.oldLeft = self.rect.left
        self.oldTop = self.rect.top

        self.image = self.images[self.direction]
        if self.direction == 'L':
            if self.rect.left > 0:
                self.rect.left -= self.speed
        elif self.direction == 'R':
            if self.rect.right < SCREEN_WIDTH:
                self.rect.left += self.speed
        elif self.direction == 'U':
            if self.rect.top > 0:
                self.rect.top -= self.speed
        elif self.direction == 'D':
            if self.rect.bottom < SCREEN_HEIGHT:
                self.rect.top += self.speed

    def stay(self):
        self.rect.left = self.oldLeft
        self.rect.top = self.oldTop

    def takeAction(self):
        """abstract function, the character takes action"""
        pass

    def hitWall(self):
        for wall in Map.wallList:
            if self.hit(wall):
                self.stay()


class AttackCharacter(Character):
    def __init__(self, left, top, speed):
        super(AttackCharacter, self).__init__(left, top, speed)
        self.direction = None

    def shot(self):
        pass


class EnemyTank(AttackCharacter):

    def __init__(self, left, top, speed, img_path='img/enemy1U.png', bullet_speed=6, shot_freq=5):

        super(EnemyTank, self).__init__(left, top, speed)
        try:
            img = pygame.image.load(img_path)
        except:  # 13
            img = pygame.image.load('img/enemy1U.png')
        self.images = {
            'U': img,
            'D': None,
            'L': None,
            'R': None
        }
        self.images['U'] = pygame.transform.scale(self.images['U'], (60, 60))
        self.images['D'] = pygame.transform.flip(pygame.transform.scale(self.images['U'], (60, 60)), False, True)
        self.images['L'] = pygame.transform.rotate(pygame.transform.scale(self.images['U'], (60, 60)), 90)
        self.images['R'] = pygame.transform.flip(pygame.transform.scale(self.images['L'], (60, 60)), True, False)

        self.direction = self.randDirection()  # random direction
        self.image = self.images[self.direction]
        self.rect = self.image.get_rect()
        # setPosition
        self.rect.left = left
        self.rect.top = top

        # AI setting, after fixed step, change direction
        self.step = 60
        self.bullet_speed = max(bullet_speed, self.speed + 1)
        self.shot_frequency = shot_freq

    def hitMyTank(self):
        if self.hit(Map.myTank):
            self.stay()

    def takeAction(self):
        # 改变敌方坦克随机移动的方向
        if self.step < 0:
            # 修改方向
            self.direction = self.randDirection()
            self.step = 60
        else:
            self.move()
            # 步数递减
            self.step -= 1

    def randDirection(self):
        """随机生成敌方坦克方向"""
        num = random.randint(1, 4)
        if num == 1:
            return 'U'
        elif num == 2:
            return 'D'
        elif num == 3:
            return 'L'
        elif num == 4:
            return 'R'

    def shot(self):
        # 随机生成100以内的数
        num = random.randint(1, 100)
        if num < self.shot_frequency:
            return Bullet(self.rect, self.direction, speed=self.bullet_speed)


class Player(Character):

    def __init__(self, left, top, speed, path='img/p1tankU.png', bullet_speed=6, bullet_capaxity=3):
        super(Player, self).__init__(left, top, speed)
        try:
            img = pygame.image.load(path)
        except:
            img = pygame.image.load('img/p1tankU.png')
        self.images = {
            'U': img,
            'D': None,
            'L': None,
            'R': None
        }
        self.images['U'] = pygame.transform.scale(self.images['U'], (60, 60))
        self.images['D'] = pygame.transform.flip(pygame.transform.scale(self.images['U'], (60, 60)), False, True)
        self.images['L'] = pygame.transform.rotate(pygame.transform.scale(self.images['U'], (60, 60)), 90)
        self.images['R'] = pygame.transform.flip(pygame.transform.scale(self.images['L'], (60, 60)), True, False)

        # direction
        self.direction = 'U'
        # query image by direction
        self.image = self.images[self.direction]
        rect = self.image.get_rect()
        self.rect.width = rect.width
        self.rect.height = rect.height
        # modyfied
        self.bullet_speed = max(bullet_speed + 1, speed)
        self.max_bullet_num = bullet_capaxity

    def takeAction(self):
        self.move()

    def shot(self):
        print(self.bullet_speed)
        return Bullet(self.rect, self.direction, speed=self.bullet_speed)

    def hitEnemyTank(self):
        """hit logic"""
        for enemyTank in Map.enemyTankList:
            if self.hit(enemyTank):
                self.stay()

    def useItem(self):
        for item in Map.itemList:
            if self.hit(item):
                if item.type == 0:
                    print("捡到道具", item.type)
                    self.bullet_speed *= 2
                    self.bullet_speed = min(self.bullet_speed, 25)
                if item.type == 1:
                    print("捡到道具", item.type)
                    self.max_bullet_num *= 3
                    self.max_bullet_num = min(20, self.max_bullet_num)
                    # print(self.bullet_speed)
                item.live = False


class Box(Character):
    def __init__(self,left,top,speed):
        super(Box, self).__init__(left, top, speed)
        img = pygame.image.load('img\\builder_block1.png')
        self.images = {
            'U': img,
            'D': img,
            'L': img,
            'R': img
        }
        # direction
        self.direction = 'U'
        # query image by direction
        self.image = self.images[self.direction]
        rect = self.image.get_rect()
        self.rect.width = rect.width
        self.rect.height = rect.height
        self.typelist=[1,2,11,21]
        self.typeWall = 1
        self.imgPath = ['img/walls.gif','img/steels.gif',"img/star.gif",'img/enemy1U.png']
        self.wallHp = [5,22e5,1,1]
        self.builder_image_path=['img\\builder_block1.png','img\\builder_block2.png','img\\builder_item1.png','img\\builder_enemy.png']
    def changeType(self):
        self.typeWall = self.typeWall%4 + 1
        img = pygame.image.load(self.builder_image_path[self.typeWall-1])
        self.images = {
            'U': img,
            'D': img,
            'L': img,
            'R': img
        }
        self.image = self.images[self.direction]
        Map.myTank.display()
        
    def takeAction(self):
        if not (round(self.rect.left / 60) * 60 == round(INIT_X / 60) * 60 and
            round(self.rect.top / 60) * 60 == round(INIT_Y / 60) * 60):
            if self.typelist[self.typeWall-1]<10 or self.typelist[self.typeWall-1]>20:
                wall = Wall((round(self.rect.left / 60) * 60), (round(self.rect.top / 60) * 60),self.wallHp[self.typeWall-1],self.imgPath[self.typeWall-1])
                Map.wallList.append(wall)
            elif self.typelist[self.typeWall-1]<20:
                item = Item((round(self.rect.left / 60) * 60), (round(self.rect.top / 60) * 60),self.imgPath[self.typeWall-1])
                Map.itemList.append(item)
            # Map.diyMap[self.rect.left // 60, self.rect.top // 60] = self.typeWall
            Map.diyMap[round(self.rect.left / 60), round(self.rect.top / 60)] = self.typelist[self.typeWall-1]